﻿Public Class Player
    Public PlayerNumber As Integer
    Public Avatar As Avatar
    Public HumanControlled As Boolean = False
    Public Cities As CityCollection
    Public CommandCenter As CommandCenter
    Public Status As PlayerStatus = PlayerStatus.Waiting
    Public Inventory As New Inventory()       
    Public playerGameStats As PlayerGameStats

    Private agressiveness As Decimal
    Private defensiveness As Decimal
    Private builder As Decimal
    Private propoganda As Decimal

    Public DeployedBomber As Bomber = Nothing

    Public _bomberDeployed As Boolean = False
    Public Property BomberDeployed() As Boolean
        Get
            Return _bomberDeployed
        End Get
        Set(ByVal value As Boolean)
            If (_bomberDeployed = False And value = True) Then
                If (DeployedBomber Is Nothing) Then
                    DeployedBomber = New Bomber(CommandCenter.Position, Me)
                End If
            End If

            _bomberDeployed = value
        End Set
    End Property

    Private _missileDeployed As MissileAndWarheadTypes = MissileAndWarheadTypes.None
    Public Property MissileDeployed() As MissileAndWarheadTypes
        Get
            Return _missileDeployed
        End Get
        Set(ByVal value As MissileAndWarheadTypes)
            _missileDeployed = value
            If (value = MissileAndWarheadTypes.None) Then
                CommandCenter.MissileDeployed = False
            Else
                CommandCenter.MissileDeployed = True
            End If
        End Set
    End Property


    Private _antiMissileDeployed As Boolean
    Public Property AntiMissileDeployed() As Boolean
        Get
            Return _antiMissileDeployed
        End Get
        Set(ByVal value As Boolean)
            _antiMissileDeployed = value
            CommandCenter.AntiMissileDeployed = value 'don't need to do this if we're not going to be drawing anything visible on the command center
        End Set
    End Property

    Private _antiAircraftDeployed As Boolean
    Public Property AntiAircraftDeployed() As Boolean
        Get
            Return _antiAircraftDeployed
        End Get
        Set(ByVal value As Boolean)
            _antiAircraftDeployed = value
            CommandCenter.AntiAircraftDeployed = value 'don't need to do this if we're not going to be drawing anything visible on the command center
        End Set
    End Property

    Public Function CheckIfDead() As Boolean
        Return Cities.AllCitiesDestroyed()
    End Function

    Public Sub New(ByVal playerNumber As Integer)
        Me.PlayerNumber = playerNumber
        Cities = PlayerCitiesFactory.GetCitiesForPlayerNumber(playerNumber)
        CommandCenter = PlayerCommandCenterFactory.getCommandCenterForPlayerNumber(playerNumber)
        playerGameStats = New PlayerGameStats(5)
    End Sub

    Public Function CanDeployBomber() As Boolean
        If (Inventory.Bombers > 0) Then
            Return True
        Else
            Return False
        End If
    End Function

    Public Function CanLaunchMissile() As Boolean
        If (CanFireExtraLargeWarhead() Or CanFireLargeWarhead() Or CanFireMediumWarhead() Or CanFireSmallWarhead()) Then
            Return True
        Else
            Return False
        End If
    End Function

    Public Function CanBomb() As Boolean
        If (BomberDeployed And (Inventory.SmallWarheads > 0 Or Inventory.MediumWarheads > 0 Or Inventory.LargeWarheads > 0)) Then
            Return True
        Else
            Return False
        End If
    End Function

    Public Function CanDeployWeapon() As Boolean
        If (Inventory.HasWeaponsToDeploy()) Then
            Return True
        Else
            Return False
        End If
    End Function

    Public Function CanDeployDefense() As Boolean
        If (Inventory.HasDefensesToDeploy()) Then
            Return True
        Else
            Return False
        End If
    End Function

    Public Function CanFireSmallWarhead() As Boolean
        If (Inventory.SmallWarheads > 0) And (MissileDeployed = MissileAndWarheadTypes.Small Or MissileDeployed = MissileAndWarheadTypes.Medium Or MissileDeployed = MissileAndWarheadTypes.Large Or MissileDeployed = MissileAndWarheadTypes.ExtraLarge) Then
            Return True
        Else
            Return False
        End If
    End Function

    Public Function CanFireMediumWarhead() As Boolean
        If (Inventory.MediumWarheads > 0) And (MissileDeployed = MissileAndWarheadTypes.Medium Or MissileDeployed = MissileAndWarheadTypes.Large Or MissileDeployed = MissileAndWarheadTypes.ExtraLarge) Then
            Return True
        Else
            Return False
        End If
    End Function

    Public Function CanFireLargeWarhead() As Boolean
        If (Inventory.LargeWarheads > 0) And (MissileDeployed = MissileAndWarheadTypes.Large Or MissileDeployed = MissileAndWarheadTypes.ExtraLarge) Then
            Return True
        Else
            Return False
        End If
    End Function

    Public Function CanFireExtraLargeWarhead() As Boolean
        If (Inventory.ExtraLargeWarheads > 0) And (MissileDeployed = MissileAndWarheadTypes.ExtraLarge) Then
            Return True
        Else
            Return False
        End If
    End Function

    Public Function BestAvailableWarheadToLaunch() As MissileAndWarheadTypes
        If (CanFireExtraLargeWarhead()) Then
            Return MissileAndWarheadTypes.ExtraLarge
        ElseIf (CanFireLargeWarhead()) Then
            Return MissileAndWarheadTypes.Large
        ElseIf (CanFireMediumWarhead()) Then
            Return MissileAndWarheadTypes.Medium
        ElseIf (CanFireSmallWarhead()) Then
            Return MissileAndWarheadTypes.Small
        Else
            Return MissileAndWarheadTypes.None
        End If
    End Function

    Public Function BestAvailableWarheadToBomb() As MissileAndWarheadTypes
        If (CanFireLargeWarhead()) Then
            Return MissileAndWarheadTypes.Large
        ElseIf (CanFireMediumWarhead()) Then
            Return MissileAndWarheadTypes.Medium
        ElseIf (CanFireSmallWarhead()) Then
            Return MissileAndWarheadTypes.Small
        Else
            Return MissileAndWarheadTypes.None
        End If
    End Function

    Public Function BestAvailableMissileToDeploy() As MissileAndWarheadTypes
        If (Inventory.ExtraLargeMissiles > 0) Then
            Return MissileAndWarheadTypes.ExtraLarge
        ElseIf (Inventory.LargeMissiles > 0) Then
            Return MissileAndWarheadTypes.Large
        ElseIf (Inventory.MediumMissiles > 0) Then
            Return MissileAndWarheadTypes.Medium
        ElseIf (Inventory.SmallMissiles > 0) Then
            Return MissileAndWarheadTypes.Small
        Else
            Return MissileAndWarheadTypes.None
        End If
    End Function

    Public Function DeterminePlayerAction() As PlayerAction
        If Not Inventory.HasWeaponsToDeploy And Not Inventory.HasDefensesToDeploy Then
            Return PlayerAction.Build
        ElseIf DetermineAttack() Then
            Return PlayerAction.Attack
        ElseIf DetermineDefend() Then
            Return PlayerAction.Defend
        Else
            Return PlayerAction.Propoganda
        End If      
    End Function

    Public Function DetermineAttack() As Boolean
        If Inventory.HasWeaponsToDeploy Then
            Return True
        Else
            Return False
        End If
    End Function

    Public Function DetermineDefend() As Boolean
        If Inventory.HasDefensesToDeploy Then
            Return True
        Else
            Return False
        End If
    End Function

    Public Function GetPlayerToAttack() As Integer
        Dim maxPlayerIndex As Integer = playerGameStats.AttackedBy.Count - 1
        Dim indexToAttack As Integer = -1
        Dim maxAttackedBy As Integer = -1
        Dim zeroCount As Integer = 0

        For Each playerID In playerGameStats.AttackedBy.Keys
            If playerGameStats.AttackedBy(PlayerNumber - 1) = 0 Then
                zeroCount = zeroCount + 1
            ElseIf playerGameStats.AttackedBy(PlayerNumber - 1) > maxAttackedBy Then
                If indexToAttack <> Me.PlayerNumber Then
                    indexToAttack = playerID
                End If
            End If
        Next
        If zeroCount = playerGameStats.AttackedBy.Count Then
            Dim randomPlayer As Integer = RandomNumberProvider.GetRandomNumber(0, 4)
            If randomPlayer <> PlayerNumber - 1 Then
                Return randomPlayer
            Else
                If randomPlayer = 4 Then
                    Return randomPlayer - 1
                ElseIf randomPlayer = 0 Then
                    Return randomPlayer + 1
                End If
            End If
        End If


        If PlayerNumber - 1 = 4 Then
            Return 3
        ElseIf PlayerNumber - 1 = 0 Then
            Return 2
        Else
            Return PlayerNumber - 1
        End If

    End Function
End Class
